﻿using Application.Common.Interfaces;
using Application.Features.Users.DTOs;
using Application.Features.Users.Specifications;
using AutoMapper;
using Common.Models;
using Domain.Entities.Identity;
using MediatR;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Common.Extensions;
using System.Linq.Dynamic.Core;
using Microsoft.EntityFrameworkCore;
using Common.Configurations;
using Microsoft.Extensions.Options;
using Common.Attributes;
namespace Application.Features.Users.Queries.Pagination;

/// <summary>
/// 用户分页查询
/// </summary>
[Description("分页查询")]
[GroupDescription(("用户管理"))]
public class UsersWithPaginationQuery : UserAdvancedFilter, IRequest<PaginatedData<UserOutput>>
{
    public override string ToString()
    {
        return
            $"Search:{Keyword},UserName:{UserName},Email:{Email},EmailConfirmed:{EmailConfirmed},PhoneNumber:{PhoneNumber},IsActive:{IsActive},OrganizationId:{OrganizationId},SortDirection:{SortDirection},OrderBy:{OrderBy},{PageNumber},{PageSize}";
    }
    [JsonIgnore]
    public UserAdvancedPaginationSpec Specification => new UserAdvancedPaginationSpec(this);
}

/// <summary>
/// 处理程序
/// </summary>
public class UsersWithPaginationQueryHandler :
IRequestHandler<UsersWithPaginationQuery,PaginatedData<UserOutput>>
{
    private readonly IMapper _mapper;
    private readonly IApplicationDbContext _context;
    private readonly IOptions<HostSettings> _hostSettingsOptions;
    public UsersWithPaginationQueryHandler(
    IApplicationDbContext context,
    IMapper mapper,
    IOptions<HostSettings> hostSettingsOptions)
    {
        _context = context;
        _mapper = mapper;
        _hostSettingsOptions = hostSettingsOptions;
    }

    /// <summary>
    /// 业务逻辑
    /// </summary>
    /// <param name="request">请求参数</param>
    /// <param name="cancellationToken">取消标记</param>
    /// <returns>返回用户分页数据</returns>
    public async Task<PaginatedData<UserOutput>> Handle(
        UsersWithPaginationQuery request,
        CancellationToken cancellationToken)
    {
        return await _context.Users
            .Include(d => d.Organization)
            .OrderBy($"{request.OrderBy} {request.SortDirection}")
            .ProjectToPaginatedDataAsync<User, UserOutput>(
                request.Specification,
                request.PageNumber,
                request.PageSize,
                _mapper.ConfigurationProvider,
                cancellationToken);
    }
}

